<?php 

/**
 * 图片的字符切割
 */

set_time_limit(0);

include './vendor/autoload.php';
include './func/func.php';
include './func/code.php';


function test0()
{
	$path= __DIR__.'/code.png';
	$img = imagecreatefrompng($path);
	img_split($img);
}
// test0();


function test1()
{
	for ($i=0; $i <6 ; $i++) { 

		// lang: fontyp, num, eng
		$text = (new TesseractOCR($i.'.png'))->lang('eng')->psm(8)->run();
		echo $text.PHP_EOL;
	}
}
// test1();


function test2()
{
	$i = 1;
	$handler = opendir(__DIR__.'/temp');
	while( ($filename = readdir($handler)) !== false ) {
		
		if($filename[0] === '.') continue;

		$base = __DIR__.'/temp/'.$filename;

		$chunk_set = img_split(imagecreatefrompng($base));

		foreach ($chunk_set as $key => $value) {
			$path = __DIR__.'/font/'.sprintf('%03d.png', $i++);
			img_draw($value, $path);
		}
	}
	closedir($handler);
	echo "Done\n";
}
test2();


/**
 * 将字符图片切分成单个字符
 * @param  resource $gd_resource 图片资源
 * @param  integer  $filter      过滤掉小于10个点的块
 * @return yet/return resource
 */
function img_split($gd_resource, $filter = 10)
{
	$w = imagesx($gd_resource);
	$h = imagesy($gd_resource);

	// 遍历所有的点
	$chunk_set = array();

	for ($i=0; $i<$w; $i++) {

	    for ($j=0; $j<$h; $j++) {

	    	// 黑点计算块区域
	    	if (isBlack(getRGB($gd_resource, $i, $j))) {
	    		$chunk  = array();
		    	$offset = img_chunk($gd_resource, $chunk, $i, $j);
		    	if (count($chunk) >= $filter) {
			    	$chunk_set[] = [$chunk, $offset];
		    	}

		    	// 使用偏移量,不需要重新裁剪
		    	$i = $offset[2];
		    	$j = $offset[3];
	    	}

	    }
	}
	
	return $chunk_set;
}


/**
 * 查找资源块
 * @param  resource  $gd_resource 图片资源
 * @param  integer   $x           位置x
 * @param  Array     $point_set   点集合
 * @param  integer   $y           位置y
 * @return Array [minX,minY,maxX,maxY]
 */
function img_chunk(&$gd_resource, Array &$point_set = [], $x=1, $y=1)
{
	// 已经统计过这个点了
	$key = "{$x}.{$y}";
	if (@$point_set[$key]) {
		return NULL;
	}

	// 白色跳出
	if (!isBlack(getRGB($gd_resource, $x, $y))) {
		return NULL;
	}

	// 保存当前
	$point_set[$key] = [$x, $y];


	$list_pos = Array();

	// 上
	$list_pos[] = img_chunk($gd_resource, $point_set, $x, $y-1);

	// 上-右
	$list_pos[] = img_chunk($gd_resource, $point_set, $x+1, $y-1);
	
	// 右
	$list_pos[] = img_chunk($gd_resource, $point_set, $x+1, $y);

	// 右-下
	$list_pos[] = img_chunk($gd_resource, $point_set, $x+1, $y+1);

	// 下
	$list_pos[] = img_chunk($gd_resource, $point_set, $x, $y+1);

	// 下-左
	$list_pos[] = img_chunk($gd_resource, $point_set, $x-1, $y+1);

	// 左
	$list_pos[] = img_chunk($gd_resource, $point_set, $x-1, $y);

	// 左-上
	$list_pos[] = img_chunk($gd_resource, $point_set, $x-1, $y-1);


	// 筛选最小的点与最大的点;
	$offset = deepin($list_pos, [$x, $y, $x, $y]);

	// 返回最小偏移点,和最大偏移点
	return $offset;
}


/**
 * 获取颜色值
 *
 * @param  [type] $gd_resource [description]
 * @param  [type] $i           [description]
 * @param  [type] $j           [description]
 * @return [type]              [description]
 */
function getRGB($gd_resource, $i, $j)
{
	$rgb = imagecolorat($gd_resource, $i, $j);
	$r = ($rgb >> 16) & 0xFF;
	$g = ($rgb >> 8) & 0xFF;
	$b = $rgb & 0xFF;
	return ['r'=>$r, 'g'=>$g, 'b'=>$b];
}


/**
 * 是否黑色,通过阀值取点
 * @param  [type]  $rgb [description]
 * @return boolean      [description]
 */
function isBlack($rgb)
{
	static $limit = ['r' => 180, 'g' => 150, 'b' => 256];
	return ($rgb['r'] < $limit['r'] 
        	&& $rgb['g'] < $limit['g'] 
        	&& $rgb['b'] < $limit['b']);
}


/**
 * 获取深度点
 * 
 * @param  Array   $list_pos 目标点
 * @param  Array   $current  当前区域
 * @return Array|null
 */
function deepin(Array $list_pos, Array $current)
{
	list($c_minX, $c_minY, $c_maxX, $c_maxY) = $current;

	foreach ($list_pos as $pos) {

		if (empty($pos)) continue;

		list($p_minX, $p_minY, $p_maxX, $p_maxY) = $pos;

		if ($p_minX < $c_minX) {
			$c_minX = $p_minX;
		}

		if ($p_minY < $c_minY) {
			$c_minY = $p_minY;
		}

		if ($p_maxX > $c_maxX) {
			$c_maxX = $p_maxX;
		}

		if ($p_maxY > $c_maxY) {
			$c_maxY = $p_maxY;
		}

	}

	return [$c_minX, $c_minY, $c_maxX, $c_maxY];
}



/**
 * 图片的点
 * @param  Array  $chunk   [description]
 * @return NULL            [description]
 */
function img_draw(Array $chunk, $name = '1.png')
{
	$list_point = $chunk[0];
	list($minX, $minY, $maxX, $maxY) = $chunk[1];
	
	$w = $maxX - $minX + 1;
	$h = $maxY - $minY + 1;
	$canvas= imagecreatetruecolor($w, $h);
	$black = imagecolorallocate($canvas, 0, 0, 0);
	$white = imagecolorallocate($canvas, 255, 255, 255);

	for ($i=0; $i<$w; $i++) {

	    for ($j=0; $j<$h; $j++) {
	    	
	    	$pos_i = $i + $minX;
	    	$pos_j = $j + $minY;
	    	$key = "{$pos_i}.{$pos_j}";
	    	if (array_key_exists($key, $list_point)) {
		    	imagesetpixel($canvas, $i, $j, $black);
	    	} else {
		    	imagesetpixel($canvas, $i, $j, $white);
	    	}

    	}
    }

    imagepng($canvas, $name);
}
